package com.pg.auth.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pg.auth.model.dto.sysmenu.*;
import com.pg.auth.model.entity.SysMenu;
import com.pg.auth.model.mapper.SysMenuMapper;
import com.pg.auth.service.SysMenuService;
import com.pg.base.component.PageVO;
import com.pg.base.component.Pager;
import com.pg.base.enums.DeleteEnum;
import com.pg.base.util.PgUtil;
import com.pg.base.vo.LoginVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/***
 * SysMenuServiceImpl
 * @author : huhuaping
 * @Date : 2024-06-06 20:59:34
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysMenuServiceImpl implements SysMenuService {

    private final SysMenuMapper sysMenuMapper;

    @Override
    public PageVO<SysMenuVO> page(Pager<SysMenuReq, SysMenuVO> pageReq){

        QueryWrapper<SysMenu> queryWrapper = baseQueryWrapper(pageReq.getParam());

        System.out.println(JSON.toJSONString(pageReq.getPageVO()));
        PageVO<SysMenuVO> result = sysMenuMapper.selectPage(pageReq.getPageVO(), queryWrapper);
        return result;
    }

    @Override
    public List<SysMenuVO> list(SysMenuReq sysMenuReq){

        QueryWrapper<SysMenu> queryWrapper = baseQueryWrapper(sysMenuReq);

        List<SysMenu> sysMenuList = sysMenuMapper.selectList(queryWrapper);

        return SysMenuConvertor.INSTANCE.listDbToVO(sysMenuList);

    }

    @Override
    public SysMenuVO getById(Long menuId) {
        SysMenu sysMenu = sysMenuMapper.selectById(menuId);
        return SysMenuConvertor.INSTANCE.dbToVO(sysMenu);
    }

    @Override
    public Long add(SysMenuDTO sysMenuDTO,LoginVO userVo) {
        SysMenu sysMenuAdd = SysMenuConvertor.INSTANCE.dtoToDB(sysMenuDTO);

        // 设置菜单编号
        QueryWrapper<SysMenu> queryWrapper =  new QueryWrapper<>();
        queryWrapper.lambda().orderByDesc(SysMenu::getMenuId);
        queryWrapper.last("limit 1");
        SysMenu lastMenu = sysMenuMapper.selectOne(queryWrapper);
        String code = lastMenu != null?lastMenu.getMenuCode():null;
        sysMenuAdd.setMenuCode(PgUtil.generateCode("M",code,6));

        //设置排序大小
        if(sysMenuAdd.getMenuSort() == null){
            QueryWrapper<SysMenu> sortQueryWrapper = new QueryWrapper<>();
            sortQueryWrapper.lambda().eq(SysMenu::getParentId, sysMenuDTO.getParentId());
            sortQueryWrapper.lambda().orderByDesc(SysMenu::getMenuSort);
            sortQueryWrapper.last("limit 1");
            SysMenu menuSort = sysMenuMapper.selectOne(sortQueryWrapper);
            int sort = menuSort!=null?menuSort.getMenuSort() : 0;
            sysMenuAdd.setMenuSort(sort + 1);
        }

        sysMenuMapper.insert(sysMenuAdd);
        return sysMenuAdd.getMenuId();
    }

    @Override
    public Integer updateById(SysMenuDTO sysMenuDTO,LoginVO userVo) {
        SysMenu sysMenuAdd = SysMenuConvertor.INSTANCE.dtoToDB(sysMenuDTO);
        int count = sysMenuMapper.updateById(sysMenuAdd);
        return count;
    }

    @Override
    public int deleteById(Long menuId) {
        SysMenu sysMenu = sysMenuMapper.selectById(menuId);

        // 封装对象
        SysMenu sysMenuDelete = new SysMenu();

        sysMenuDelete.setMenuId(menuId);
        sysMenuDelete.setDeleteStatus(DeleteEnum.DELETE.getValue());

        return sysMenuMapper.updateById(sysMenuDelete);

    }

    @Override
    public List<SysMenuTreeVO> listMenuTree(SysMenuReq sysMenuReq){

        QueryWrapper<SysMenu> queryWrapper = baseQueryWrapper(sysMenuReq);

        List<SysMenu> sysMenuList = sysMenuMapper.selectList(queryWrapper);

        List<SysMenuTreeVO> menuVOList = SysMenuConvertor.INSTANCE.listDbToTreeVO(sysMenuList);

        // 根据SysId分组
        if (ObjectUtil.isNotEmpty(menuVOList)) {
            Map<Integer, List<SysMenuTreeVO>> groupByParentIdMap = menuVOList.stream().collect(Collectors.groupingBy(SysMenuTreeVO::getSysId));
//            subSysList.forEach(subSys -> {
//                SubSysMenuResp subSysMenuResp = BeanUtil.toBean(subSys, SubSysMenuResp.class);
//                subSysMenuResp.setSubSysName(subSysMenuResp.getSubSysName()+"["+subSysMenuResp.getDescribed()+"]");
//                subSysMenuResp.setMenuTreeList(packageMenuTree(groupByParentIdMap.get(subSysMenuResp.getSubSysId()), MenuParentIdEnum.PARENT_ID_ENUM.getValue()));
//                list.add(subSysMenuResp);
//            });
        }

        List<SysMenuTreeVO> sysMenuTreeVOS = packageMenuTree(menuVOList, 0L);

        return sysMenuTreeVOS;

    }


    /**
     * 构造子系统菜单树
     * @param menuList  菜单列表
     * @return list
     */
    private List<SysMenuTreeVO> packageMenuTree(List<SysMenuTreeVO> menuList , Long parentId) {
        List<SysMenuTreeVO> menuTreeRespList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(menuList)) {
            for (SysMenuTreeVO menu : menuList) {
                if( ObjectUtil.isNotEmpty(parentId) && parentId.equals(menu.getParentId()) ){
                    menu.setChildren(packageMenuTree(menuList, menu.getMenuId()));
                    menuTreeRespList.add(menu);
                }
            }
        }
        return menuTreeRespList;
    }


    private QueryWrapper<SysMenu> baseQueryWrapper(SysMenuReq sysMenu) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SysMenu> lambda =  queryWrapper.lambda();
        lambda.eq(SysMenu::getDeleteStatus,DeleteEnum.NORMAL.getValue());
            lambda.orderByDesc(SysMenu::getMenuId);
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuId())) {
            lambda.eq(SysMenu::getMenuId, sysMenu.getMenuId());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuKey())) {
            lambda.eq(SysMenu::getMenuKey, sysMenu.getMenuKey());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuCode())) {
            lambda.like(SysMenu::getMenuCode, sysMenu.getMenuCode());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuName())) {
            lambda.like(SysMenu::getMenuName, sysMenu.getMenuName());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuStatus())) {
            lambda.eq(SysMenu::getMenuStatus, sysMenu.getMenuStatus());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuType())) {
            lambda.eq(SysMenu::getMenuType, sysMenu.getMenuType());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuSort())) {
            lambda.eq(SysMenu::getMenuSort, sysMenu.getMenuSort());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuUrl())) {
            lambda.eq(SysMenu::getMenuUrl, sysMenu.getMenuUrl());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuIcon())) {
            lambda.eq(SysMenu::getMenuIcon, sysMenu.getMenuIcon());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuIconSelected())) {
            lambda.eq(SysMenu::getMenuIconSelected, sysMenu.getMenuIconSelected());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getMenuSvg())) {
            lambda.eq(SysMenu::getMenuSvg, sysMenu.getMenuSvg());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getOpenNewWin())) {
            lambda.eq(SysMenu::getOpenNewWin, sysMenu.getOpenNewWin());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getParentId())) {
            lambda.eq(SysMenu::getParentId, sysMenu.getParentId());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getSysId())) {
            lambda.eq(SysMenu::getSysId, sysMenu.getSysId());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getRenderType())) {
            lambda.eq(SysMenu::getRenderType, sysMenu.getRenderType());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getRemark())) {
            lambda.eq(SysMenu::getRemark, sysMenu.getRemark());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getCreateUser())) {
            lambda.eq(SysMenu::getCreateUser, sysMenu.getCreateUser());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getCreateUserName())) {
            lambda.eq(SysMenu::getCreateUserName, sysMenu.getCreateUserName());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getCreateTime())) {
            lambda.eq(SysMenu::getCreateTime, sysMenu.getCreateTime());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getUpdateUser())) {
            lambda.eq(SysMenu::getUpdateUser, sysMenu.getUpdateUser());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getUpdateUserName())) {
            lambda.eq(SysMenu::getUpdateUserName, sysMenu.getUpdateUserName());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getUpdateTime())) {
            lambda.eq(SysMenu::getUpdateTime, sysMenu.getUpdateTime());
        }
        if (ObjectUtil.isNotEmpty(sysMenu.getDeleteStatus())) {
            lambda.eq(SysMenu::getDeleteStatus, sysMenu.getDeleteStatus());
        }
        return queryWrapper;
    }

}
